import { success, failed } from '@gnlab/utils'
import type { Cell, CellRichTextValue } from 'exceljs'

// eslint-disable-next-line @typescript-eslint/consistent-type-imports
export type Excel = typeof import('exceljs')

export function useExceljs() {
  const [exceljs, setExceljs] = useState<Excel | null>(null)
  useEffect(() => void import('exceljs').then(lib => setExceljs(lib)), [])
  return exceljs
}

export function getCellValue(cell: Cell) {
  const rawText = cell.text as string | CellRichTextValue
  if (typeof rawText === 'object' && 'richText' in rawText) {
    return rawText.richText.map(v => v.text).join('')
  }
  return String(rawText).trim()
}

export async function parseExcel<T>(
  Excel: Excel,
  file: ArrayBuffer,
  columns: { name: string; key: string }[], // name: excel 中的列名；key: 生成对象的字段名
) {
  try {
    const workbook = new Excel.Workbook()
    const book = await workbook.xlsx.load(file)
    const sheet = book.worksheets[0]
    if (!sheet) return failed('Excel 格式错误：缺少 worksheet')

    const headerRow = sheet.getRow(1)
    for (let no = 1; no <= columns.length; no++) {
      const columnTitle = getCellValue(headerRow.getCell(no))
      const expectColumnTitle = columns[no - 1]?.name ?? ''
      if (expectColumnTitle !== columnTitle)
        return failed(`Excel 格式错误：列名不匹配“${columnTitle}”应为“${expectColumnTitle}”`)
    }

    const results: T[] = []
    for (let no = 2; no < sheet.rowCount; no++) {
      const row = sheet.getRow(no)
      const values = columns.map(({ key }, index) => ({
        key,
        value: getCellValue(row.getCell(index + 1)).trim(),
      }))
      if (values.every(item => !item.value)) continue

      const object = values.reduce<Record<string, string>>(
        (obj, { key, value }) => ({ ...obj, [key]: value }),
        {},
      )
      results.push(object as unknown as T)
    }

    return success(results)
  } catch (e) {
    return failed(`Excel 解析失败：${String(e)}`)
  }
}
